#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>

#define task_num 10
typedef void(*task_s)();
task_s task[task_num];
void InitTask()
{
    int i=0;
    for(;i<task_num;i++)
    {
        task[i]=NULL;
    }
}

void task1()
{
    printf("打印日志任务 pid=%d\n",getpid());
}

void task2()
{
    printf("网络健康状态任务 pid=%d\n",getpid());
}

void task3()
{
    printf("绘制图形界面任务 pid=%d\n",getpid());
}

int AddTask(task_s t)
{
    int pos=0;
    for(;pos<task_num;pos++)
    {
        if(!task[pos]) break;
    }

    if(pos==task_num)
        return -1;
    task[pos]=t;
    return 0;
}

void UseStake()
{
    int i=0;
    for(;i<task_num;i++)
    {
        if(!task[i]) continue;
            task[i]();
    }
}

void Child()
{
    int cnt=5;
    while(cnt)
    {
        printf("I am child pid=%d ppid=%d cnt=%d\n",getpid(),getppid(),cnt);
        sleep(1);
        cnt--;
    }
}

int main()
{
    pid_t pid=fork();
    if(pid==0)
    {
        Child();
        exit(11);
    }
    if(pid>0)
    {    
        printf("I am parent pid=%d ppid=%d\n",getpid(),getppid());
    }

    //sleep(8);//不需要等待，需要非阻塞查询
    InitTask();
    AddTask(task1);
    AddTask(task2);
    AddTask(task3);
    int status=0;
    while(1)
    {
        
        pid_t ret=waitpid(pid,&status,WNOHANG);//第三个参数是非阻塞，就会有三个返回值
        //大于0 等于0 小于0
        if(ret>0)
        {
            printf("waitpid success ret=%d\n",ret);
            if(WIFEXITED(status))
            {
                printf("进程是正常跑完的->signal:%d,waitcode:%d\n",status&0x7F,(status)>>8&0xFF);
                
               // printf("signal:%d,waitcode:%d\n",WIFEXITED(status),WEXITSTATUS(status));
            }
            else{
                printf("进程出异常了\n");
            }
            break;
        }
        else if(ret<0)
        {
            printf("等待失败\n");
            break;
        }
        else{
            //ret==0
            //printf("子进程还没有退出，我再等等...\n");
            //sleep(1);
            UseStake(); 
            usleep(500000);
        }
    }

    sleep(3);
    return 0;
}
